﻿using MediaBot.Entities;
using System;
using System.Collections;
using System.Text;
using System.Xml;

namespace MediaBot.Library
{
    public class XmlWebPage: WebPage
    {
        private XmlDocument _doc;
        private XmlNamespaceManager _nsManager;
        private ArrayList _namespaces;

        public XmlWebPage(Uri uri, ArrayList namespaces): base(uri)
        {
            this._namespaces = namespaces;
        }

        public override void Dispose()
        {
            _doc = null;
            _nsManager = null;
            base.Dispose();
        }

        public override void Download()
        {
            int numberOfRetries = 3;
            while (numberOfRetries > 0)
            {
                try
                {
                    StringBuilder sb = new StringBuilder(base.DownloadPage());
                    string text = sb.ToString();
                    _doc = new XmlDocument { PreserveWhitespace = true, XmlResolver = null };

                    var i = sb.ToString().IndexOf("<rss");
                    if (i == -1)
                    {
                        using (var xhtmlConverter = new Sgml.SgmlReader())
                        {
                            xhtmlConverter.DocType = "HTML";
                            xhtmlConverter.WhitespaceHandling = System.Xml.WhitespaceHandling.All;
                            xhtmlConverter.IgnoreDtd = true;
                            xhtmlConverter.CaseFolding = Sgml.CaseFolding.ToLower;
                            xhtmlConverter.InputStream = new System.IO.StringReader(sb.ToString());
                            _doc.Load(xhtmlConverter);
                            xhtmlConverter.Close();
                        }
                    }
                    else
                    {
                        _doc.LoadXml(sb.ToString().Substring(i));
                    }

                    this.RefreshXmlNamespaceManager();
                    numberOfRetries = 0;
                }
                catch (Exception)
                {
                    numberOfRetries--;
                    if (numberOfRetries > 0)
                        continue;
                    throw;
                }
            }
        }

        private void RefreshXmlNamespaceManager()
        {
            if (this._doc == null)
                this._nsManager = null;

            this._nsManager = new XmlNamespaceManager(this._doc.NameTable);
            foreach (NamespaceUriItem item in this._namespaces)
            {
                this._nsManager.AddNamespace(item.Name, item.Value);
            }
        }

        public XmlNodeList SelectNodes(string xpath)
        {
            return this._doc.SelectNodes(xpath, this._nsManager);
        }

        public XmlNode SelectSingleNode(string xpath, XmlNamespaceManager nsmng)
        {
            var namespaces = nsmng == null ? this._nsManager : nsmng;
            return this._doc.SelectSingleNode(xpath, namespaces);
        }

        public XmlNamespaceManager XmlNamespaceManager 
        {
            get
            {
                return this._nsManager;
            }
        }

        public string GetString(MatchType pattern)
        {
            return pattern.GetString(this._doc, this._nsManager);
        }

        public string GetData()
        {
            if (this._doc != null)
                return this._doc.OuterXml;
            return string.Empty;
        }

        
    }
}
